package cn.sycoder.controller;

import cn.sycoder.entity.Menu;
import cn.sycoder.entity.Role;
import cn.sycoder.entity.RoleMenu;
import cn.sycoder.exception.BusinessException;
import cn.sycoder.mapper.RoleMapper;
import cn.sycoder.mapper.RoleMenuMapper;
import cn.sycoder.resp.Code;
import cn.sycoder.resp.ListResp;
import cn.sycoder.resp.TreeResp;
import cn.sycoder.service.IMenuService;
import cn.sycoder.service.IRoleMenuService;
import cn.sycoder.service.IRoleService;
import cn.sycoder.utils.JsonUtil;
import cn.sycoder.utils.JwtUtil;
import cn.sycoder.utils.MenusUtil;
import cn.sycoder.vo.MenuVo;
import cn.sycoder.vo.RoleMenuVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.type.TypeReference;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 杨润发
 * @since 2024-10-20
 */
@RestController
@RequestMapping("/api")
@Api(tags = "角色管理")
@Transactional(rollbackFor = Exception.class)
public class RoleController {

    @Autowired
    IRoleService service;

    @Autowired
    RoleMapper mapper;

    @Autowired
    IMenuService menuService;

    @Autowired
    RoleMenuMapper roleMenuMapper;

    @Autowired
    IRoleMenuService roleMenuService; // 角色菜单权限

    @PostMapping("/Role/list")
    @ApiOperation(value = "角色管理-获取角色列表")
    public Map<String, Object> roleList(@RequestParam(defaultValue = "1") int page,
                                        @RequestParam(defaultValue = "10") int limit,
                                        @RequestParam(value = "roleName", required = false) String roleName,
                                        @RequestParam(value = "roleNo", required = false) String roleNo) {
        // 创建返回结果
        Map<String, Object> response = new HashMap<>();

        // 创建分页查询
        Page<Role> objectPage = new Page<>(page, limit);

        // 构造sql
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        Map<String, Object> params = new HashMap<>();
        params.put("role_name", roleName);
        params.put("role_no", roleNo);
        wrapper.allEq(params, false); // 如果条件中参数为空时，则从条件中去除该参数


        Page<Role> rolePage = null;
        try {
            // 执行分页查询
            rolePage = mapper.selectPage(objectPage, wrapper);
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }

        if (rolePage != null) {
            // 获取角色总数
            long count = rolePage.getTotal();
            response.put("count", count);
            response.put("data", rolePage);
            response.put("success", true);
        } else {
            response.put("success", false);
            response.put("msg", "服务器异常！");
        }
        return response;
    }


    @PostMapping("/Role/save")
    @ApiOperation(value = "角色管理-保存（添加编辑）")
    public Map<String, Object> roleSave(@RequestParam(value = "roleId", required = false) Long roleId,
                                        @RequestParam(value = "systemNo") String systemNo,
                                        @RequestParam(value = "roleName") String roleName,
                                        @RequestParam(value = "roleNo") String roleNo,
                                        @RequestParam(value = "token") String token) {

        // 创建响应结果
        Map<String, Object> response = new HashMap<>();
//        boolean ret = service.roleSave(roleId, systemNo, roleName, roleNo, token);

        // 获取登录用户名（修改人）
        String username = JwtUtil.extractUsername(token);


        Role role = new Role();
        role.setRoleId(roleId);
        role.setSystemNo(systemNo);
        role.setRoleName(roleName);
        role.setRoleNo(roleNo);
        // 设置修改人
        role.setEditUser(username);
        // 设置修改时间
        role.setEditTime(new Date());

        // 保存或更新方法
        boolean ret = false;
        try {
            if (role.getRoleId() != null) {
                // 有id表示更新操作
                ret = service.updateById(role);
            } else {
                // 无id表示保存操作
                ret = service.save(role);
            }
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }

        if (ret) {
            response.put("success", true);
        } else {
            response.put("msg", "服务器异常！");
        }
        return response;
    }


    @DeleteMapping("/Role/delete")
    @ApiOperation(value = "角色管理-删除角色")
    public Map<String, Object> roleDelete(@RequestParam("ids") Long roleId) {

        // 删除角色菜单权限
        roleMenuMapper.deleteByRoleId(roleId);

        // 创建响应结果
        Map<String, Object> response = new HashMap<>();

        try {
            // 执行删除操作
            boolean ret = service.removeById(roleId);
            if (ret) {
                response.put("success", true);
            } else {
                response.put("msg", "服务器异常");
            }
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }
        return response;
    }


    @GetMapping("/RoleRight/tree/{roleId}")
    @ApiOperation(value = "角色管理-菜单权限（获取）")
//    public TreeResp roleRightTree(@PathVariable("roleId") Long roleId) {
    public Map<String, Object> roleRightTree(@PathVariable("roleId") Long roleId) {

        List<Menu> menus = null;
        try {
            // 先找没有子菜单的，再去查询有子菜单的
            menus = menuService.list();
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }

        List<MenuVo> parentMenus = new ArrayList<>();
        List<MenuVo> sonMenus = new ArrayList<>();
        for (Menu menu : menus) {
            MenuVo menuVo = new MenuVo();
            BeanUtils.copyProperties(menu, menuVo);
            if (menu.getPid() == null) {
                parentMenus.add(menuVo);
            }
            sonMenus.add(menuVo);
        }

        // 按照MenuVo对象的orderValue属性进行排序
        List<MenuVo> parentOrderMenus = parentMenus.stream()
                .sorted(Comparator.comparing(MenuVo::getOrderValue))
                .collect(Collectors.toList());

        // 遍历已经排好序的父菜单列表parentOrderMenus
        for (MenuVo orderMenu : parentOrderMenus) {
            // 获取当前父菜单orderMenu（通过其ID识别）对应的子菜单列表
            List<MenuVo> child = MenusUtil.getChild(orderMenu.getId(), sonMenus);
            // 按照子菜单MenuVo对象的orderValue属性进行排序
            List<MenuVo> collect = child.stream()
                    .sorted(Comparator.comparing(MenuVo::getOrderValue))
                    .collect(Collectors.toList());
            orderMenu.setMenus(collect);
        }

//        TreeResp ret = new TreeResp<>();
//        ret.setData(parentOrderMenus);

        List<RoleMenu> roleMenus = null;
        try {
            // 查询角色所拥有的菜单
            roleMenus = roleMenuMapper.roleMenus(roleId); // 使用mapper自定义 sql
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }
//        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();  // 构造sql
//        wrapper.eq("role_id",roleId);
//        List<RoleMenu> roleMenus = roleMenuService.list(wrapper);
//        ret.setList(roleMenus);
//        return ret;
        HashMap<String, Object> response = new HashMap<>();
        if (parentOrderMenus != null) {
            response.put("success", true);
            response.put("data", parentOrderMenus);
            response.put("list", roleMenus);
        } else {
            response.put("success", false);
            response.put("msg", "服务器异常！");
        }
        return response;
    }


    @PostMapping("/RoleRight/save")
    @ApiOperation(value = "角色管理-菜单权限（保存）")
    public Map<String, Object> roleRightSave(@RequestParam("roleId") Long roleId,
                                             @NotNull @RequestParam("moduleIds") List<Long> menuIds) {
        // 创建响应结果
        HashMap<String, Object> response = new HashMap<>();
        boolean ret;
        try {
            ret = roleMenuService.saveRoleRights(roleId, menuIds);
            if (ret) {
                response.put("success", true);
            } else {
                response.put("msg", "服务器异常！");
            }
        } catch (BusinessException e) {
            new BusinessException(Code.BUSINESS_ERR, "处理业务异常，请稍后再试！");
        }
        return response;
    }
}
